package com.yyfax.pay.quartz.dynamic;

import java.util.Date;

import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.Assert;

import com.yyfax.pay.quartz.model.vo.DynamicJobVO;

/**
 * 对JOb操作的核心类
 *
 * @author admin
 */
public final class DynamicSchedulerFactory implements InitializingBean {

	private static final Logger LOG = LoggerFactory.getLogger(DynamicSchedulerFactory.class);

	private static Scheduler scheduler;

	public DynamicSchedulerFactory() {
	}

	public void setScheduler(Scheduler scheduler) {
		DynamicSchedulerFactory.scheduler = scheduler;
	}

	/**
	 * Register a job
	 * 添加(注册)一个动态的JOB
	 *
	 * @param job DynamicJob
	 * @return True is register successful
	 * @throws SchedulerException
	 */
	public static boolean registerJob(DynamicJobVO job) throws SchedulerException {
		final TriggerKey triggerKey = job.triggerKey();
		if (scheduler == null) {
			LOG.warn("调度器没有初始化，请检查相关配置");
			return false;
		}

		if (scheduler.checkExists(triggerKey)) {
			final Trigger trigger = scheduler.getTrigger(triggerKey);
			throw new SchedulerException("Already exist trigger [" + trigger + "] by key [" + triggerKey + "] in Scheduler");
		}

		final CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.cronExpression());
		final CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();

		final JobDetail jobDetail = job.jobDetail();
		final Date date = scheduler.scheduleJob(jobDetail, cronTrigger);

		LOG.info("Register DynamicJob {} on [{}]", job, date);
		return true;
	}

	/**
	 * Update an exist job
	 * 更新一个动态的JOB
	 *
	 * @param job DynamicJob
	 * @return True is register successful
	 * @throws SchedulerException
	 */
	public static boolean updateJob(DynamicJobVO job) throws SchedulerException {
		// final TriggerKey triggerKey = job.triggerKey();
		// if (!scheduler.checkExists(triggerKey)) {
		// throw new SchedulerException("Not exist trigger by key [" + triggerKey + "] in Scheduler");
		// }
		// final CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.cronExpression());
		// final CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
		//
		// final Date date = scheduler.rescheduleJob(triggerKey, cronTrigger);
		// LOG.debug("Update DynamicJob {} on [{}]", job, date);

		boolean isRomve = removeJob(job);
		if (!isRomve) {
			LOG.error("更新任务失败，DynamicJob {}", job);
			return false;
		}

		boolean registerJob = registerJob(job);
		LOG.debug("Update DynamicJob {} on [{}]", job, registerJob);
		return true;
	}

	/*
	 * Pause exist job
	 * 暂停已经存在的JOB
	 */
	public static boolean pauseJob(DynamicJobVO existJob) throws SchedulerException {
		final TriggerKey triggerKey = existJob.triggerKey();
		boolean result = false;
		if (scheduler.checkExists(triggerKey)) {
			scheduler.pauseTrigger(triggerKey);
			result = true;
			LOG.debug("Pause exist DynamicJob {}, triggerKey [{}] successful", existJob, triggerKey);
		} else {
			LOG.debug("Failed pause exist DynamicJob {}, because not fount triggerKey [{}]", existJob, triggerKey);
		}
		return result;
	}

	/*
	 * Resume exist job
	 * 重启一个JOB
	 */
	public static boolean resumeJob(DynamicJobVO existJob) throws SchedulerException {
		final TriggerKey triggerKey = existJob.triggerKey();
		boolean result = false;
		if (scheduler.checkExists(triggerKey)) {
			final CronTrigger newTrigger = existJob.cronTrigger();
			final Date date = scheduler.rescheduleJob(triggerKey, newTrigger);

			result = true;
			LOG.debug("Resume exist DynamicJob {}, triggerKey [{}] on [{}] successful", existJob, triggerKey, date);
		} else {
			LOG.debug("Failed resume exist DynamicJob {}, because not fount triggerKey [{}]", existJob, triggerKey);
		}
		return result;
	}

	// /**
	// * Checking the job is existed or not
	// * 检查JOB是否存在
	// *
	// * @param job Job
	// * @return True is existed, otherwise false
	// * @throws SchedulerException
	// */
	// public static boolean existedJob(DynamicJobVO job) throws SchedulerException {
	// final TriggerKey triggerKey = job.triggerKey();
	// return scheduler.checkExists(triggerKey);
	// }

	/**
	 * 判断job是否已经存在
	 * 
	 * @author buyi
	 * @date 2017-09-21 10:45:29
	 * @since v2.0.0
	 * @param job
	 * @return
	 * @throws SchedulerException
	 */
	public static boolean exist(DynamicJobVO job) throws SchedulerException {
		return scheduler.checkExists(job.jobDetail().getKey());

	}

	/**
	 * Remove exists job
	 * 删除一个已经存在的JOB
	 *
	 * @param existJob A DynamicJob which exists in Scheduler
	 * @return True is remove successful
	 * @throws SchedulerException
	 */
	public static boolean removeJob(DynamicJobVO existJob) throws SchedulerException {
		// final TriggerKey triggerKey = existJob.triggerKey();
		boolean result = false;

		// if (scheduler.checkExists(triggerKey)) {
		// final JobDetail jobDetail = existJob.jobDetail();
		// result = scheduler.deleteJob(jobDetail.getKey());
		// }
		if (exist(existJob)) {
			result = scheduler.deleteJob(existJob.jobDetail().getKey());
		} else {
			result = true;
		}

		LOG.info("Remove DynamicJob {} result [{}]", existJob, result);
		return result;
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		Assert.notNull(scheduler, "scheduler is null");
		LOG.info("Initial DynamicSchedulerFactory successful, scheduler instance: {}", scheduler);
	}

}